import { useCallback, useEffect, useRef, useState } from "react";
import GpuCanvas from "../../components/GpuCanvas";
import DatGui, {
  DatSelect,
  DatFolder,
  DatBoolean,
  DatNumber,
} from "react-dat-gui";

type SimulateType = {
  simulate: Boolean;
  deltaTime: number;
  toneMappingMode: GPUCanvasToneMappingMode;
  brightnessFactor: number;
};
export default function Particles() {
  const appName = "Particles";
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [selectedData, setSelectedData] = useState<SimulateType>({
    simulate: true,
    deltaTime: 0.04,
    toneMappingMode: "standard" as GPUCanvasToneMappingMode,
    brightnessFactor: 1.0,
  });
  const [folderName, setFolderName] = useState("");
  const hdrMediaQuery = window.matchMedia("(dynamic-range: high)");
  useEffect(() => {
    const onHdrMediaQueryChange = () => {
      if (!canvasRef.current) return;
      setFolderName(getHdrFolderName(canvasRef.current as HTMLCanvasElement));
    };
    hdrMediaQuery.addEventListener("change", onHdrMediaQueryChange);
    return () => {
      hdrMediaQuery.removeEventListener("change", onHdrMediaQueryChange);
    };
  });
  function getHdrFolderName(canvas: HTMLCanvasElement) {
    const context = canvas.getContext("webgpu");
    if (!context) {
      return "";
    }
    if (!hdrMediaQuery.matches) {
      return "HDR settings ⚠️ Display isn't compatible";
    }
    if (!("getConfiguration" in GPUCanvasContext.prototype)) {
      return "HDR settings";
    }
    if (
      selectedData.toneMappingMode === "extended" &&
      context.getConfiguration().toneMapping.mode !== "extended"
    ) {
      return "HDR settings ⚠️ Browser doesn't support HDR canvas";
    }
    return "HDR settings";
  }
  const onDataUpdate = useCallback(
    (data: SimulateType) => {
      setSelectedData(data);
    },
    [selectedData]
  );

  const onCanvasUpdate = useCallback(
    (canvas: HTMLCanvasElement) => {
      canvasRef.current = canvas;
      setFolderName(getHdrFolderName(canvas));
    },
    [selectedData]
  );
  return (
    <div
      style={{
        width: "100%",
        height: "100%",
      }}
    >
      <GpuCanvas app={appName} data={selectedData} callback={onCanvasUpdate} />
      <DatGui data={selectedData} onUpdate={onDataUpdate}>
        <DatBoolean path="simulate" />
        <DatNumber path="deltaTime" min={0.01} max={0.1} step={0.001} />
        <DatFolder title={folderName} closed={false}>
          <DatSelect
            path="toneMappingMode"
            options={["standard", "extended"]}
          />
          <DatNumber path="brightnessFactor" min={0.0} max={4.0} step={0.1} />
        </DatFolder>
      </DatGui>
    </div>
  );
}
